#include <iostream>
#include <iomanip>
#include "equationsolver.h"
#include <limits>

const double pi = acos(-1);
const double eps = std::numeric_limits<double>::epsilon();
double D = 55;
using namespace std;

double f(double x){
    double l = 89;
    double beta1 = 11.5 / 180 * pi;   //角度转弧度
    double h = 49;
    double A = l * sin(beta1);
    double B = l * cos(beta1);
    double C = (h + 0.5 * D) * sin(beta1) - 0.5 * D * tan(beta1);
    double E = (h + 0.5 * D) * cos(beta1) - 0.5 * D;
    return A * sin(x) * cos(x) + B * sin(x) * sin(x) - C * cos(x) - E * sin(x);
}

double df(double x){
    double l = 89;
    double beta1 = 11.5 / 180 * pi;   //角度转弧度
    double h = 49;
    double A = l * sin(beta1);
    double B = l * cos(beta1);
    double C = (h + 0.5 * D) * sin(beta1) - 0.5 * D * tan(beta1);
    double E = (h + 0.5 * D) * cos(beta1) - 0.5 * D;
    return A * cos(2*x) + B * sin(2*x) + C * sin(x) - E * cos(x);
}

int main()
{
    typedef double (*fp)(double);
    fp fpi = f;
    fp dfpi = df;
    myfunc f(fpi,dfpi);
    cout << "Question F: " << endl;

    cout << "(a) Choose x0 = pi/4" << endl;
    D = 55;
    newton N(pi/4.0,eps,100,f);
    double alpha = N.solve();
    cout << "The Newton result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << alpha << endl;
    cout << "Change unit: alpha = " << setiosflags(ios::fixed) << setprecision(2) << alpha * 180 / pi << " degree" << endl;
    cout << endl;

    cout << "(b) Choose x0 = 33 degree" << endl;
    D = 30;
    newton N2(33.0 / 180.0 * pi,eps,100,f);
    cout << "The Newton result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << N2.solve() * 180 / pi << " degree" << endl;
    cout << endl;

    cout << "(c) Choose x1 = 33 degree, x0 = 75 degree " << endl;
    secant S(75.0 / 180.0 * pi,33.0 / 180.0 * pi,eps,eps,100,f);
    cout << "The Secant result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << S.solve() * 180 / pi << " degree" << endl;
    cout << "Choose x1 = 33 degree, x0 = 393 degree " << endl;
    secant S2(393 / 180.0 * pi,33.0 / 180.0 * pi,eps,eps,100,f);
    cout << "The Secant result of alpha is " << setiosflags(ios::fixed) << setprecision(2) << S2.solve() * 180 / pi << " degree" << endl;

    return 0;
}